package com.carbon.system.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carbon.system.entity.CarbonArticleComment;
import com.carbon.system.entity.UserAccessToken;
import com.carbon.system.mapper.CarbonArticleCommentMapper;
import com.carbon.system.param.CarbonArticleParam;
import com.carbon.system.common.BaseController;
import com.carbon.system.param.CarbonArticleStatuParam;
import com.carbon.system.service.CarbonArticleService;
import com.carbon.system.param.CarbonArticleQueryParam;
import com.carbon.system.service.FeishuFiletokenService;
import com.carbon.system.service.SysAccountService;
import com.carbon.system.util.CommonUtil;
import com.carbon.system.vo.CarbonArticleAddVo;
import com.carbon.system.vo.CarbonArticleQueryVo;
import com.carbon.system.entity.CarbonArticle;
import com.carbon.domain.common.ApiResult;
import com.carbon.common.api.Paging;
import com.carbon.system.vo.CarbonArticleReturnVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.view.RedirectView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


/**
 * <p>
 * 碳文章 前端控制器
 * </p>
 *
 * @author Li Jun
 * @since 2021-08-01
 */
@Slf4j
@RestController
@RequestMapping("/carbonArticle")
@Api(value = "碳文章模块", tags = {"碳文章模块"})
public class CarbonArticleController extends BaseController {
    @Autowired
    private CarbonArticleService carbonArticleService;
    @Autowired
    private SysAccountService sysAccountService;
    @PostMapping("/search")
    @ApiOperation(value = "查询碳文章")
    public ApiResult<CarbonArticleReturnVo> search(@RequestBody CarbonArticleQueryParam param){
        Page<CarbonArticle> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        if(param.getStatus()!=null){
        param.setStatus(sysAccountService.transactionexC(param.getStatus()));}
        IPage<CarbonArticle> paging = carbonArticleService.search(page,param);
        CarbonArticleReturnVo exchangeAccountQueryReturnVo = new CarbonArticleReturnVo();
        exchangeAccountQueryReturnVo.setList(paging.getRecords());
        for (int i = 0; i < exchangeAccountQueryReturnVo.getList().size(); i++) {
            exchangeAccountQueryReturnVo.getList().get(i).setStatus(sysAccountService.transactionNumberToChinese(exchangeAccountQueryReturnVo.getList().get(i).getStatus()));
        }
        exchangeAccountQueryReturnVo.setTotal((int) paging.getTotal());
        return ApiResult.ok(exchangeAccountQueryReturnVo);
    }
    //offline
    @PostMapping("/offlineOrPublish")
    @ApiOperation(value = "上下线碳文章")
    public ApiResult<Boolean> offlineOrUpdate(@RequestBody CarbonArticleStatuParam param){
        if(param.getStatus().equals("已下线")) param.setStatus("0260000002");
        else if (param.getStatus().equals("已发布")) {
            param.setStatus("0260000003");
        }else if (param.getStatus().equals("未发布")) {
            param.setStatus("0260000002");
        }
        Boolean flag = carbonArticleService.offlineOrUpdate(param);
        return ApiResult.result(flag);
    }
    //删除
    @PostMapping("/delete")
    @ApiOperation(value = "删除碳文章")
    public ApiResult<Boolean> delete(@RequestBody Map<String, String> params){
        String id = params.get("id");
        Boolean flag = carbonArticleService.removeById(id);
        return ApiResult.result(flag);
    }

    /**
     * 创建飞书文档（前端点击“添加文章”时调用）
     */
    @PostMapping("/create-feishu-doc")
    public ApiResult<String> createFeishuDoc() {
        String feishuDoc = carbonArticleService.createFeishuDoc();
        return ApiResult.ok(feishuDoc);
    }

    /**
     * 同步飞书文档内容（前端点击“同步文章”时调用）
     */
    @PostMapping("/sync-feishu-doc")
    public ApiResult syncFeishuDoc(String accessToken) {
        carbonArticleService.syncFeishuDoc(accessToken);
        return ApiResult.ok();
    }
    /**
     * 授权
     */
    @GetMapping("/sync-article")
    public RedirectView startSyncArticle() {
        String scope = "docx:document drive:drive contact:contact.base:readonly contact:user.base:readonly contact:user.employee_id:readonly";
        String state = UUID.randomUUID().toString().replace("-", "");
        String url = CommonUtil.buildAuthorizationUrl("cli_a81787fdaafa5013", "http://localhost:9091/system/carbonArticle/oauth/callback", scope, state);

        // 4. 重定向到飞书授权页
        return new RedirectView(url);
    }
    /**
     * 处理授权回调，获取 code
     */
    @RequestMapping("/oauth/callback")
    public String handleOAuthCallback(HttpServletRequest request) {
        // 从请求参数中获取授权码
        String code = request.getParameter("code");
        String state = request.getParameter("state");

        // 验证 state（防止 CSRF 攻击）
//        if (!validateState(state)) {
//            throw new RuntimeException("state 验证失败");
//        }

        // 使用 code 换取 user_access_token
        if (code != null && !code.isEmpty()) {
            UserAccessToken token = getAccessTokenByCode(code, "cli_a81787fdaafa5013", "tm8yLTlybhflGQvaYWwJMeQpAI61KiXh");
            // 存储 token 供后续使用
            //saveAccessToken(token);
            carbonArticleService.syncFeishuDoc(token.getAccessToken());
            return "同步文章成功，请返回";
        }

        throw new RuntimeException("获取授权码失败: " + request.getParameter("error"));
    }
    /**
     * 使用授权码 code 获取 user_access_token
     * @param code 授权码
     * @param appId 应用 App ID
     * @param appSecret 应用 App Secret
     * @return 用户访问凭证
     */
    public UserAccessToken getAccessTokenByCode(String code, String appId, String appSecret) {
        // 请求参数
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("grant_type", "authorization_code");
        requestBody.put("client_id", appId);
        requestBody.put("client_secret", appSecret);
        requestBody.put("code", code);
        // 如果是网页应用，需要传递 redirect_uri，且与授权时的一致
        requestBody.put("redirect_uri", "http://localhost:9091/system/carbonArticle/oauth/callback");

        // 发送请求
        String response = HttpUtil.createPost("https://open.feishu.cn/open-apis/authen/v2/oauth/token")
                .header("Content-Type", "application/json; charset=utf-8")
                .body(JSONUtil.toJsonStr(requestBody))
                .execute()
                .body();

        // 解析响应
        JSONObject json = JSONUtil.parseObj(response);
        if (json.getInt("code") != 0) {
            throw new RuntimeException("获取 user_access_token 失败: " + json.getStr("msg"));
        }

        // 封装结果
        UserAccessToken token = new UserAccessToken();
        token.setAccessToken(json.getStr("access_token"));
        token.setExpiresIn(json.getInt("expires_in"));
        token.setRefreshToken(json.getStr("refresh_token"));
        token.setTokenType(json.getStr("token_type"));
        token.setScope(json.getStr("scope"));

        return token;
    }
    /**
     * 使用 refresh_token 刷新 user_access_token
     */
    public UserAccessToken refreshAccessToken(String refreshToken, String appId, String appSecret) {
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("grant_type", "refresh_token");
        requestBody.put("client_id", appId);
        requestBody.put("client_secret", appSecret);
        requestBody.put("refresh_token", refreshToken);

        String response = HttpUtil.createPost("https://open.feishu.cn/open-apis/authen/v2/oauth/token")
                .header("Content-Type", "application/json; charset=utf-8")
                .body(JSONUtil.toJsonStr(requestBody))
                .execute()
                .body();

        // 解析响应（与获取 token 逻辑类似）
        JSONObject json = JSONUtil.parseObj(response);
        if (json.getInt("code") != 0) {
            throw new RuntimeException("刷新 token 失败: " + json.getStr("msg"));
        }

        UserAccessToken token = new UserAccessToken();
        token.setAccessToken(json.getStr("access_token"));
        token.setExpiresIn(json.getInt("expires_in"));
        token.setRefreshToken(json.getStr("refresh_token"));
        token.setTokenType(json.getStr("token_type"));
        token.setScope(json.getStr("scope"));

        return token;
    }

}

